﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using POSPlus.QueuedBackgroundWorker;
using POSPlus.QueryCreator;
using POSPlus.DatabaseOperations;
using System.Text.RegularExpressions;
using POSPlus.EZBarTender.DatabaseOperations;

namespace POSPlus.EZBarTender
{
    /// <summary>
    /// <para>Filters the selected batches by Department, Group, Section, Subscription or UPC.  It also
    /// includes the ability to filter with by SVTregPrintTagFlag and Hosted fields in the POSBdat.</para>
    /// 
    /// <para>It writes the filtered information to a temporary data base to prevent the queries from
    /// becoming to large for the SQL server to handle.  This temporary table is dropped before anything
    /// is written and immediately after the print job is sent to the printer.</para>
    /// 
    /// <para>It adds entries to the Printer Controller with the correct sign type selected.</para>
    /// </summary>
    public partial class BatchFilter : Form
    {
        private BatchPrinter _instanceRef;
        private DataSet _set;
        private BackgroundableDataGridView _topView;
        private BackgroundableDataGridView _bottomView;
        private Queue<QueueItem<SqlCommand>> _queryQueue = new Queue<QueueItem<SqlCommand>>();

        private Select everythingFields = new Select(new string[] { "Description", "Vendor", "Cert_Code", "AvgDailyMovement", "Pack", "Size", "Unit_NP", "UOM", "Hosted", "PriceMethod", "Normal_Price", "GroupPrice", "Quantity", "UPC", "LocAisle", "LocBlock", "LocSeq", "SpecialPriceMethod", "Special_Price", "SpecialGroupPrice", "SpecialQuantity", "PalletCode", "Unit_SP", "WhereToBuy", "StartDate", "EndDate", "Rehang", "BatchNo", "TagType", "JobName" });
		private Select regularFields = new Select(new String[] { "Description", "Vendor", "Cert_Code", "AvgDailyMovement", "Pack", "Size", "Unit_NP", "UOM", "Hosted", "PriceMethod", "Normal_Price", "GroupPrice", "Quantity", "UPC", "LocAisle", "LocBlock", "LocSeq", "BatchNo", "TagType", "JobName" });
		
        private Select select = new Select(new string[] { "Description", "Vendor", "Cert_Code", "AvgDailyMovement", "Pack", "Size", "Unit_NP", "UOM", "Hosted", "PriceMethod", "Normal_Price", "GroupPrice", "Quantity", "UPC", "LocAisle", "LocBlock", "LocSeq", "SpecialPriceMethod", "Special_Price", "SpecialGroupPrice", "SpecialQuantity", "PalletCode", "Unit_SP", "WhereToBuy", "Start_Date AS StartDate", "End_Date AS EndDate", "Rehang", "BatchNo", "'Test' AS TagType", "'Test' AS JobName" });
        private Select dsdSelect = new Select(new string[] { "Description", "Vendor", "Cert_Code", "AvgDailyMovement", "Pack", "Size", "Unit_NP", "UOM", "Hosted", "PriceMethod", "Normal_Price", "GroupPrice", "Quantity", "UPC", "LocAisle", "LocBlock", "LocSeq", "SpecialPriceMethod", "Special_Price", "SpecialGroupPrice", "SpecialQuantity", "PalletCode", "Unit_SP", "WhereToBuy", "Start_Date AS StartDate", "DealEndDate AS EndDate", "Rehang", "BatchNo", "'Test' AS TagType", "'Test' AS JobName" });

		private Select regularSelect = new Select(new String[] { "Description", "Vendor", "Cert_Code", "AvgDailyMovement", "Pack", "Size", "Unit_NP", "UOM", "Hosted", "PriceMethod", "Normal_Price", "GroupPrice", "Quantity", "UPC", "LocAisle", "LocBlock", "LocSeq", "BatchNo" });
		private Select specialSelect = new Select(new String[] { "SpecialPriceMethod", "Special_Price", "SpecialGroupPrice", "SpecialQuantity", "PalletCode", "Unit_SP", "WhereToBuy", "Start_Date", "End_Date", "Rehang", "DealEndDate" });
		private Select regularWithRSelect = new Select(new String[] { "r.Description", "r.Vendor", "r.Cert_Code", "r.AvgDailyMovement", "r.Pack", "r.Size", "r.Unit_NP", "r.UOM", "r.Hosted", "r.PriceMethod", "r.Normal_Price", "r.GroupPrice", "r.Quantity", "r.UPC", "r.LocAisle", "r.LocBlock", "r.LocSeq", "r.BatchNo" });
		private Select specialWithSSelect = new Select(new String[] { "s.SpecialPriceMethod", "s.Special_Price", "s.SpecialGroupPrice", "s.SpecialQuantity", "s.PalletCode", "s.Unit_SP", "s.WhereToBuy", "s.Start_Date", "s.End_Date", "s.Rehang", "s.DealEndDate" });
		
        private string _taggedTable = "POSplus_TagLoc_ProdBats";

        private TagType _tagType;

		private BackgroundWorker _printManagerTransfer;

        public BatchFilter()
        {
            InitializeComponent();
        }

        public BatchFilter(BatchPrinter parent, TagType tagType, string table)
        {
            _taggedTable = table;
			switch (_taggedTable)
			{
				case "POSplus_TagLoc_ProdBats":
					_table = "ProductBatches";
					break;
				case "POSplus_TagLoc_DSD_FPB":
					_table = "POSplus_DSD_FuturePB";
					break;
			}
            _instanceRef = parent;
            Location = parent.Location;
            Size = parent.Size;
            WindowState = parent.WindowState;
            InitializeComponent();
            _set = new DataSet();
            _set.Tables.Add("Search");
            _set.Tables.Add("Print");
            _set.Tables.Add("UPC Search");
            _tagType = tagType;
            initializeGridViews();
			_printManagerTransfer = new BackgroundWorker();
			_printManagerTransfer.DoWork += new DoWorkEventHandler(_printManagerTransfer_DoWork);
			_printManagerTransfer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_printManagerTransfer_RunWorkerCompleted);
        }

		public BatchFilter(BatchPrinter parent, TagType tagType, string table, string[] batchNos)
			: this(parent, tagType, table)
		{
			_batchNos = batchNos;
			_top = new DataTable();
			_bottom = new DataTable();
		}

        private void BatchFilter_Load(object sender, EventArgs e)
        {
            _instanceRef.Visible = false;
			_buttonAllInBatch.Checked = true;
        }

        private void _btnBatchPrinter_Click(object sender, EventArgs e)
        {
            _instanceRef.Location = Location;
            _instanceRef.Size = Size;
            _topView.DataSource = null;
            _instanceRef.Visible = true;

            Visible = false;
        }

        private void initializeGridViews()
        {
            _topView = new BackgroundableDataGridView();
            _topView.Location = new Point(11, 4);
            _topView.Size = new Size(_viewPanel.Width - 22, _btnAdd.Location.Y - 8);
            _viewPanel.Controls.Add(_topView);

            _topPictureBox.Location = new Point((_viewPanel.Width / 2) - (_topPictureBox.Width / 2),
                (_topView.Location.Y + (_topView.Height / 2)) - (_topPictureBox.Height / 2));
            _bottomView = new BackgroundableDataGridView();
            _bottomView.Location = new Point(11, _btnAdd.Location.Y + _btnAdd.Height + 4);
            _bottomView.Size = new Size(_viewPanel.Width - 22, (_viewPanel.Height - 8) - (_btnAdd.Location.Y + _btnAdd.Height));
            _bottomPictureBox.Location = new Point((_viewPanel.Width / 2) - (_bottomPictureBox.Width / 2),
                (_bottomView.Location.Y + (_bottomView.Height / 2)) - (_bottomPictureBox.Height / 2));
            _viewPanel.Controls.Add(_bottomView);

			_topView.RowsAdded += new DataGridViewRowsAddedEventHandler(_topView_RowsAdded);
			_topView.RowsRemoved += new DataGridViewRowsRemovedEventHandler(_topView_RowsRemoved);
			_bottomView.RowsAdded += new DataGridViewRowsAddedEventHandler(_bottomView_RowsAdded);
			_bottomView.RowsRemoved += new DataGridViewRowsRemovedEventHandler(_bottomView_RowsRemoved);
        }

		void _bottomView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
		{
			if (_bottomView.Rows.Count < 1)
			{
				_btnRemove.Enabled = false;
				_btnRemoveAll.Enabled = false;
				_addToPrinterController.Enabled = false;
			}
			_printManagerItemCountLabel.Text = _bottomView.Rows.Count.ToString();
		}

		void _bottomView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
		{
			if (e.RowCount > 0)
			{
				_btnRemove.Enabled = true;
				_btnRemoveAll.Enabled = true;
				_addToPrinterController.Enabled = true;
			}
			_printManagerItemCountLabel.Text = _bottomView.Rows.Count.ToString();
		}

		void _topView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
		{
			if (_topView.Rows.Count < 1)
			{
				_btnAdd.Enabled = false;
			}
			_itemCountLabel.Text = _topView.Rows.Count.ToString();
		}

		void _topView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
		{
			if (e.RowCount > 0)
				_btnAdd.Enabled = true;

			_itemCountLabel.Text = _topView.Rows.Count.ToString();
		}

        private void BatchFilter_FormClosing(object sender, FormClosingEventArgs e)
        {
            _instanceRef.Close();
        }

        private void BatchFilter_Resize(object sender, EventArgs e)
        {
            _topView.Size = new Size(_viewPanel.Width - 22, _btnAdd.Location.Y - 8);
            _topPictureBox.Location = new Point((_viewPanel.Width / 2) - (32 / 2),
                (_topView.Location.Y + (_topView.Height / 2)) - (32 / 2));
            _bottomView.Location = new Point(11, _btnAdd.Location.Y + _btnAdd.Height + 4);
            _bottomView.Size =
                new Size(_viewPanel.Width - 22, (_viewPanel.Height - 8) - (_btnAdd.Location.Y + _btnAdd.Height));
            _bottomPictureBox.Location = new Point((_viewPanel.Width / 2) - (_bottomPictureBox.Width / 2),
                 (_bottomView.Location.Y + (_bottomView.Height / 2)) - (_bottomPictureBox.Height / 2));
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] arguments = (string[])e.Argument;
            string connectionString = _instanceRef.ConnectionString;

			using (SqlConnection connection = new SqlConnection(connectionString))
			{
				connection.Open();
				using (SqlDataAdapter adapter = new SqlDataAdapter(arguments[0], connection))
				{
					if (!arguments[1].Equals("UPC Search") && !arguments[1].Equals("Print"))
					{
						ClearDataTable(_top);
					}
					try
					{
						adapter.Fill(_top);
						RemoveDuplicates(_top);
					}
					catch (SqlException ex)
					{
						MessageBox.Show(ex.Message + "\nSQL Statement: " + arguments[0]);
					}
					e.Result = arguments[1];
				}
				connection.Close();
			}
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
			try
			{
				string result = (string)e.Result;
				if (result.Equals("Search"))
				{
					BindDataSource(_topView, _top);
				}
				else if (result.Equals("UPC Search"))
				{
					BindDataSource(_topView, _top);
				}
				_bottomPictureBox.Visible = false;
				_topPictureBox.Visible = false;
			}
			catch
			{
				MessageBox.Show("You would have had a lock up.", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			finally
			{
				controlsEnabled(true);
			}
        }

        private void controlsEnabled(bool p)
        {
            _btnBoth.Enabled = p;
            _btnDepartment.Enabled = p;
            _btnGroup.Enabled = p;
            _btnN.Enabled = p;
            _btnSection.Enabled = p;
            _btnSubscription.Enabled = p;
            _btnUPC.Enabled = p;
            _btnVendor.Enabled = p;
            _btnY.Enabled = p;
            _btnModifiedDate.Enabled = p;
			_buttonAllInBatch.Enabled = p;
			_btnRehang.Enabled = p;
			_dateTimePicker.Enabled = p;
			_dateTimePicker2.Enabled = p;

            if (_btnModifiedDate.Checked)
            {
                _dateTimePicker.Enabled = p;
                _dateTimePicker2.Enabled = p;
            }
        }

        private void _btnSection_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnSection.Checked)
            {
				ChangeInnerOption(GetSections(), "Section: ", false);
       
            }
        }

        private void _btnVendor_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnVendor.Checked)
            {
				ChangeInnerOption(GetVendors(), "Vendors: ", false);
            }
        }

        private void _btnGroup_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnGroup.Checked)
            {
				ChangeInnerOption(GetGroups(), "Groups: ", false);
            }
        }

		private void _btnRehang_CheckedChanged(object sender, EventArgs e)
		{
			if (_btnRehang.Checked)
			{
				ChangeInnerOption(GetRehangs(), "Rehangs: ", false);
			}
		}

        private void _btnSubscription_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnSubscription.Checked)
            {
				ChangeInnerOption(GetAisles(), "Aisle: ", true);
            }
        }

        private void _btnDepartment_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnDepartment.Checked)
            {
				ChangeInnerOption(GetDepartmentNames(), "Departments: ", false);
            }
        }

		private void _buttonAllInBatch_CheckedChanged(object sender, EventArgs e)
		{
			if (_buttonAllInBatch.Checked)
			{
				_innerOptionsComboBox.Visible = false;
				_innerOptionsLabel.Visible = false;
				_secondaryOptionComboBox.Visible = false;
				_secondaryOptionLabel.Visible = false;


				DataTable newTop = new DataTable();
				newTop = GetDataFromCommandString(GetAllItems());
				_topView.Focus();
				ClearDataTable(_top);
				_top = newTop;
				BindDataSource(_topView, _top);
			}
		}

        private void _btnModifiedDate_CheckedChanged(object sender, EventArgs e)
        {
            modifiedDateSearch();
        }

        private void _btnSearch_Click(object sender, EventArgs e)
        {
            Query query = new Query(
                new Select(new string[] { "UPC", "Cert_Code", "Description", "Size", "LocAisle", "LocBlock", "LocSeq", "BatchNo" }),
                new From(_taggedTable));

            if (_btnY.Checked)
                query.AddWhereExpression("SVTregPrintTagFlag = 'Y'", "AND");
            else if (_btnN.Checked)
                query.AddWhereExpression("SVTregPrintTagFlag = 'N'", "AND");

            List<string> ors = new List<string>();
            foreach (string word in _txtSearch.Text.Split(','))
                ors.Add(parseWord(word));

            query.AddWhereExpressions("AND", ors.ToArray(), "OR");

            ors = new List<string>();
            foreach (DataGridViewRow row in _instanceRef.BGDataGridView.SelectedRows)
                ors.Add("BatchNo = '" + row.Cells["BatchNo"].Value + "'");

            query.AddWhereExpressions("AND", ors.ToArray(), "OR");

            _topPictureBox.Visible = true;
            _txtSearch.Text = "";
            _txtSearch.Focus();
            controlsEnabled(false);
            backgroundWorker.RunWorkerAsync(new string[] { query.ToString(), "UPC Search" });
        }

        private string parseWord(string word)
        {
            string results = "";

            if (word.Contains("-"))
            {
                string[] split = word.Split('-');
                if (split.Length == 2)
                {
                    string first = "'" + upcExpand(split[0]) + "'";
                    string second = "'" + upcExpand(split[1]) + "'";
                    results = String.Format("UPC BETWEEN {0} AND {1}", first, second);
                }
            }
            else
            {
                results = String.Format("UPC = '{0}'", upcExpand(word));
            }

            return results;
        }

        private string upcExpand(string word)
        {
            string result = word;

            if (word.Length == 6)
            {
                string lastDigit = word.Substring(word.Length - 1);

                word.Remove(word.Length - 1);

                switch (lastDigit)
                {
                    case "0": result = word.Insert(2, "00000"); break;
                    case "1": result = word.Insert(2, "10000"); break;
                    case "2": result = word.Insert(2, "20000"); break;
                    case "3": result = word.Insert(3, "00000"); break;
                    case "4": result = word.Insert(4, "00000"); break;
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                    case "9": result = word.Insert(5, "0000" + lastDigit); break;
                }
            }

            while (result.Length < 13)
                result = "0" + result;

            return result;
        }

        private void _btnUPC_CheckedChanged(object sender, EventArgs e)
        {
			_txtSearch.Enabled = _btnUPC.Checked;
            if (_btnUPC.Checked)
            {
				ClearDataTable(_top);
				_innerOptionsComboBox.Visible = false;
				_innerOptionsLabel.Visible = false;
				_secondaryOptionComboBox.Visible = false;
				_secondaryOptionLabel.Visible = false;


                _txtSearch.Focus();
                if (_txtSearch.Text.Length > 0)
                    _btnSearch.Enabled = true;
                else
                    _btnSearch.Enabled = false;
            }
            else
            {
				_set.Tables["UPC Search"].Rows.Clear();
                _txtSearch.Text = "";
                _txtSearch.Enabled = false;
                _btnSearch.Enabled = false;
            }
        }

        private void _txtSearch_TextChanged(object sender, EventArgs e)
        {
            if (_txtSearch.Text.Length > 0)
            {
                _btnSearch.Enabled = true;
            }
            else
            {
                _btnSearch.Enabled = false;
            }
        }

        private void _btnAdd_Click(object sender, EventArgs e)
        {
			if (_bottom.Rows.Count < 1)
				_bottom = _top.Clone();

			foreach (DataGridViewRow selectedRow in _topView.SelectedRows)
			{
				DataRow row = ((DataRowView)selectedRow.DataBoundItem).Row;
				_bottom.ImportRow(row);
			}

			RemoveDuplicates(_bottom);

			BindDataSource(_bottomView, _bottom);
        }

		private void _addAllButton_Click(object sender, EventArgs e)
		{
			if (_bottom.Rows.Count < 1)
				_bottom = _top.Clone();

			foreach (DataGridViewRow row in _topView.Rows)
			{
				DataRow dataRow = ((DataRowView)row.DataBoundItem).Row;
				_bottom.ImportRow(dataRow);
			}

			RemoveDuplicates(_bottom);

			BindDataSource(_bottomView, _bottom);
		}

        private void _dateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            if (_dateTimePicker.Value > _dateTimePicker2.Value)
                _dateTimePicker2.Value = _dateTimePicker.Value;
            else
            {
                modifiedDateSearch();
            }
        }

        private void _dateTimePicker2_ValueChanged(object sender, EventArgs e)
        {
            if (_dateTimePicker2.Value < _dateTimePicker.Value)
                _dateTimePicker.Value = _dateTimePicker2.Value;
            else
            {
                modifiedDateSearch();
            }
        }

        private void _btnRemoveAll_Click(object sender, EventArgs e)
        {
			ClearDataTable(_bottom);
        }

        private void _btnRemove_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in _bottomView.SelectedRows)
                _bottomView.Rows.Remove(row);
        }

        private void _btnY_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnY.Checked)
            {
                if (_btnVendor.Checked)
                {
                    _btnVendor.Checked = false;
                    _btnVendor.PerformClick();
                }
                else if (_btnUPC.Checked)
                {
                    _btnUPC.Checked = false;
                    _btnUPC.PerformClick();
                }
                else if (_btnSubscription.Checked)
                {
                    _btnSubscription.Checked = false;
                    _btnSubscription.PerformClick();
                }
                else if (_btnSection.Checked)
                {
                    _btnSection.Checked = false;
                    _btnSection.PerformClick();
                }
                else if (_btnModifiedDate.Checked)
                {
                    _btnModifiedDate.Checked = false;
                    _btnModifiedDate.PerformClick();
                }
                else if (_btnGroup.Checked)
                {
                    _btnGroup.Checked = false;
                    _btnGroup.PerformClick();
                }
                else if (_btnDepartment.Checked)
                {
                    _btnDepartment.Checked = false;
                    _btnDepartment.PerformClick();
                }
				else if (_buttonAllInBatch.Checked)
				{
					_buttonAllInBatch.Checked = false;
					_buttonAllInBatch.PerformClick();
				}
            }
        }

        private void _btnN_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnN.Checked)
            {
                if (_btnVendor.Checked)
                {
                    _btnVendor.Checked = false;
                    _btnVendor.PerformClick();
                }
                else if (_btnUPC.Checked)
                {
                    _btnUPC.Checked = false;
                    _btnUPC.PerformClick();
                }
                else if (_btnSubscription.Checked)
                {
                    _btnSubscription.Checked = false;
                    _btnSubscription.PerformClick();
                }
                else if (_btnSection.Checked)
                {
                    _btnSection.Checked = false;
                    _btnSection.PerformClick();
                }
                else if (_btnModifiedDate.Checked)
                {
                    _btnModifiedDate.Checked = false;
                    _btnModifiedDate.PerformClick();
                }
                else if (_btnGroup.Checked)
                {
                    _btnGroup.Checked = false;
                    _btnGroup.PerformClick();
                }
                else if (_btnDepartment.Checked)
                {
                    _btnDepartment.Checked = false;
                    _btnDepartment.PerformClick();
				}
				else if (_buttonAllInBatch.Checked)
				{
					_buttonAllInBatch.Checked = false;
					_buttonAllInBatch.PerformClick();
				}
            }
        }

        private void _btnBoth_CheckedChanged(object sender, EventArgs e)
        {
            if (_btnBoth.Checked)
            {
                if (_btnVendor.Checked)
                {
                    _btnVendor.Checked = false;
                    _btnVendor.PerformClick();
                }
                else if (_btnUPC.Checked)
                {
                    _btnUPC.Checked = false;
                    _btnUPC.PerformClick();
                }
                else if (_btnSubscription.Checked)
                {
                    _btnSubscription.Checked = false;
                    _btnSubscription.PerformClick();
                }
                else if (_btnSection.Checked)
                {
                    _btnSection.Checked = false;
                    _btnSection.PerformClick();
                }
                else if (_btnModifiedDate.Checked)
                {
                    _btnModifiedDate.Checked = false;
                    _btnModifiedDate.PerformClick();
                }
                else if (_btnGroup.Checked)
                {
                    _btnGroup.Checked = false;
                    _btnGroup.PerformClick();
                }
                else if (_btnDepartment.Checked)
                {
                    _btnDepartment.Checked = false;
                    _btnDepartment.PerformClick();
				}
				else if (_buttonAllInBatch.Checked)
				{
					_buttonAllInBatch.Checked = false;
					_buttonAllInBatch.PerformClick();
				}
            }
		}

		void _printManagerTransfer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			if(e.Result != null)
				if (e.Result.ToString().StartsWith("Error Adding", StringComparison.CurrentCultureIgnoreCase))
				{		
					MessageBox.Show(this, 
						e.Result.ToString(), 
						"Print Manager Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			_addToPrinterController.Text = "Add to Print Manager";
			_addToPrinterController.Enabled = true;
			if (JobAdded != null)
				JobAdded(this, EventArgs.Empty);
		}

		void _printManagerTransfer_DoWork(object sender, DoWorkEventArgs e)
		{
			Object[] args = (Object[])e.Argument;
			List<Dictionary<string,string>> upcs = (List<Dictionary<String, String>>)args[0];
			List<String> selectedRows = (List<String>)args[1];
			TagType type = (TagType)args[2];

			foreach (Dictionary<string, string> upc in upcs)
			{
				Product p = new Product(_instanceRef.ConnectionString, upc["Upc"]);
				if (_taggedTable == "POSplus_TagLoc_DSD_FPB")
				{
					FutureProdBat bat;
					if (string.IsNullOrEmpty(upc["LocAisle"]))
					{
						bat = new FutureProdBat(_instanceRef.ConnectionString, upc["Upc"], "DSDwareHousePricing");
						p = new Product(_instanceRef.ConnectionString, upc["Upc"]);
					}
					else
					{
						bat = new FutureProdBat(_instanceRef.ConnectionString, upc["Upc"], "DSDwareHousePricing",
							int.Parse(upc["LocAisle"]), int.Parse(upc["LocBlock"]), int.Parse(upc["LocSeq"]));
						p = new Product(_instanceRef.ConnectionString, upc["Upc"]);
					}
					string jobName = _txtPrintJobDescription.Text;

					if (p.LabelWidth == "SM")
					{
						jobName += " Small Labels";
						switch (type)
						{
							case TagType.BonusBucks: type = TagType.SmallBonusBucks;
								break;
							case TagType.NowEvenLower: type = TagType.SmallNowEvenLower;
								break;
							case TagType.Regular: type = TagType.SmallRegular;
								break;
							case TagType.RegularDiscontinued: type = TagType.SmallRegularDiscontinued;
								break;
							case TagType.SmartBuy: type = TagType.SmallSmartBuy;
								break;
							case TagType.SpecialDeal: type = TagType.SmallSpecialDeal;
								break;
							case TagType.SuperSale: type = TagType.SmallSuperSale;
								break;
						}
					}
					else
					{
						switch (type)
						{
							case TagType.SmallBonusBucks: type = TagType.BonusBucks;
								break;
							case TagType.SmallNowEvenLower: type = TagType.NowEvenLower;
								break;
							case TagType.SmallRegular: type = TagType.Regular;
								break;
							case TagType.SmallRegularDiscontinued: type = TagType.RegularDiscontinued;
								break;
							case TagType.SmallSmartBuy: type = TagType.SmartBuy;
								break;
							case TagType.SmallSpecialDeal: type = TagType.SpecialDeal;
								break;
							case TagType.SmallSuperSale: type = TagType.SuperSale;
								break;
						}
					}
					PrintManagerDisplay display = new PrintManagerDisplay(_instanceRef.ConnectionString);
					display.BatchNo = bat.BatchNo;
					display.LocAisle = bat.LocAisle;
					display.LocBlock = bat.LocBlock;
					display.LocSeq = bat.LocSeq;
					display.Upc = bat.Upc;
					display.JobName = jobName;
					display.Type = GetDisplayType(type);
					try
					{
						display.Create();
					}
					catch (Exception ex)
					{
						if (ex.Message.Contains("duplicate") || ex.Message.Contains("Duplicate"))
							e.Result = "Unable to add item to Print Manager\n\nA job with the same name already exists.";
						else
							e.Result = "Error Adding:\n" + display.ToString() + "\nto Print Manager\n\n" + ex.Message;
					}
					
				}
				else
				{
					ProdBat bat;
					if (string.IsNullOrEmpty(upc["LocAisle"]))
					{
						bat = new ProdBat(_instanceRef.ConnectionString, upc["Upc"], selectedRows.ToArray());
					}
					else
					{
						bat = new ProdBat(_instanceRef.ConnectionString, upc["Upc"], selectedRows.ToArray(),
							int.Parse(upc["LocAisle"]), int.Parse(upc["LocBlock"]), int.Parse(upc["LocSeq"]));
					}

					string jobName = _txtPrintJobDescription.Text;

					if (p.LabelWidth == "SM")
					{
						jobName += " Small Labels";
						switch (type)
						{
							case TagType.BonusBucks: type = TagType.SmallBonusBucks;
								break;
							case TagType.NowEvenLower: type = TagType.SmallNowEvenLower;
								break;
							case TagType.Regular: type = TagType.SmallRegular;
								break;
							case TagType.RegularDiscontinued: type = TagType.SmallRegularDiscontinued;
								break;
							case TagType.SmartBuy: type = TagType.SmallSmartBuy;
								break;
							case TagType.SpecialDeal: type = TagType.SmallSpecialDeal;
								break;
							case TagType.SuperSale: type = TagType.SmallSuperSale;
								break;
						}
					}
					else
					{
						switch (type)
						{
							case TagType.SmallBonusBucks: type = TagType.BonusBucks;
								break;
							case TagType.SmallNowEvenLower: type = TagType.NowEvenLower;
								break;
							case TagType.SmallRegular: type = TagType.Regular;
								break;
							case TagType.SmallRegularDiscontinued: type = TagType.RegularDiscontinued;
								break;
							case TagType.SmallSmartBuy: type = TagType.SmartBuy;
								break;
							case TagType.SmallSpecialDeal: type = TagType.SpecialDeal;
								break;
							case TagType.SmallSuperSale: type = TagType.SuperSale;
								break;
						}
					}

					PrintManagerDisplay display = new PrintManagerDisplay(_instanceRef.ConnectionString);
					display.BatchNo = bat.BatchNo;
					display.LocAisle = bat.LocAisle;
					display.LocBlock = bat.LocBlock;
					display.LocSeq = bat.LocSeq;
					display.Upc = bat.Upc;
					display.JobName = jobName;
					display.Type = GetDisplayType(type);
					try
					{
						display.Create();
					}
					catch (Exception ex)
					{
						if (ex.Message.Contains("duplicate") || ex.Message.Contains("Duplicate"))
						{
							e.Result = "Unable to add item to Print Manager\n\nA job with the same name already exists.";
						}
						else
							e.Result = "Error Adding:\n" + display.ToString() + "\nto Print Manager\n\n" + ex.Message;
					}
				}
			}
		}

		private string GetDisplayType(TagType type)
		{
			switch (type)
			{
				case TagType.BonusBucks: return "6UPBB";
				case TagType.NowEvenLower: return "6UPNEL";
				case TagType.Regular: return "18UPREG";
				case TagType.RegularDiscontinued: return "18UPREGD";
				case TagType.SmartBuy: return "6UPSB";
				case TagType.SpecialDeal:
					if (_taggedTable == "POSplus_TagLoc_DSD_FPB") return "6UPSDF";
					else return "6UPSD";
				case TagType.SuperSale: return "6UPSS";
				case TagType.SmallBonusBucks: return "12UPBB";
				case TagType.SmallNowEvenLower: return "12UPNEL";
				case TagType.SmallRegular: return "32UPREG";
				case TagType.SmallRegularDiscontinued: return "32UPREGD";
				case TagType.SmallSmartBuy: return "12UPSB";
				case TagType.SmallSpecialDeal:
					if (_taggedTable == "POSplus_TagLoc_DSD_FPB")
						return "12UPSDF";
					else
						return "12UPSD";
				case TagType.SmallSuperSale: return "12UPSS";
				default: return "FAIL";
			}
		}

        private void _addToPrinterController_Click(object sender, EventArgs e)
        {
			_addToPrinterController.Enabled = false;
			_addToPrinterController.Text = "Adding...";
			List<Dictionary<String,String>> upcs = new List<Dictionary<String, String>>();
			foreach (DataGridViewRow row in _bottomView.Rows)
			{
				Dictionary<String, String> stringedItem = new Dictionary<string, string>();
				stringedItem.Add("Upc",row.Cells["Upc"].Value.ToString());
				stringedItem.Add("LocAisle", row.Cells["LocAisle"].Value.ToString());
				stringedItem.Add("LocBlock", row.Cells["LocBlock"].Value.ToString());
				stringedItem.Add("LocSeq", row.Cells["LocSeq"].Value.ToString());
				upcs.Add(stringedItem);
			}
			List<String> batchNos = new List<String>();
			foreach (DataGridViewRow row in _instanceRef.BGDataGridView.SelectedRows)
			{
				batchNos.Add(row.Cells["BatchNo"].Value.ToString());
			}

			Object[] args = new Object[] { upcs, batchNos, _tagType };
			_printManagerTransfer.RunWorkerAsync(args);
        }

        private void AddQueue(SqlCommand sqlCommand, ProgressBar progressBar)
        {
            QueuedBackgroundWorker.QueuedBackgroundWorker.QueueWorkItem(
                _queryQueue,
                sqlCommand,
                args =>
                {
                    try
                    {
                        sqlCommand.Connection.Open();
                        int rowsAffected = sqlCommand.ExecuteNonQuery();
                        sqlCommand.Dispose();
                        return new { QueryCount = _queryQueue.Count, RowsAffected = rowsAffected };
                    }
                    catch (InvalidOperationException ex)
                    {
                        Console.WriteLine(ex.ToString());
                        sqlCommand.Dispose();
                        return new { QueryCount = -1, RowsAffected = -1 };
                    }
                    catch (SqlException ex)
                    {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(sqlCommand.CommandText);
                        sqlCommand.Dispose();
                        return new { QueryCount = -1, RowsAffected = -1 };
                    }
                },
                args =>
                {
                    if (progressBar != null)
                        progressBar.Value = args.Result.QueryCount;

                    try
                    {
                        sqlCommand.Connection.Close();
                    }
                    catch (InvalidOperationException ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    catch (SqlException ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    finally
                    {
                        sqlCommand.Dispose();
                    }
                });
        }

        private void BatchFilter_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
            {
                string title = "";
                foreach (DataGridViewRow row in _instanceRef.BGDataGridView.SelectedRows)
                    title += row.Cells["BatchNo"].Value + ", ";
                title = title.Substring(0, title.Length - 2);

                Text = title + " - Batch Filter - EZBarTender";
            }
        }

        public string TableName { get { return _taggedTable; } set { _taggedTable = value; } }

		public delegate void JobAddedEventHandler(Object sender, EventArgs e);
		public event JobAddedEventHandler JobAdded;




		/****************************************************************************************
		 * 
		 * IMPROVEMENTS
		 * 
		 ****************************************************************************************/
		private String[] _batchNos;
		private String _table;
		private BindingList<String> _innerOptions;
		private BindingList<String> _secondaryOptions;
		private DataTable _top;
		private DataTable _bottom;

		private String BatchNoString
		{
			get
			{
				String result = "";
				foreach (String s in _batchNos)
				{
					if (result.Length > 0)
						result += ",";
					result += "'" + s + "'";
				}
				return result;
			}
		}

		private void ClearDataTable(DataTable table)
		{
			try
			{
				table.Clear();
			}
			catch (DataException)
			{
				MessageBox.Show(this, table.TableName + " could not be cleared.", "Table Clear Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void BindDataSource(DataGridView view, DataTable table)
		{
			BindingSource source = new BindingSource();
			source.DataSource = table;
			view.DataSource = source;
		}

		private void ChangeInnerOption(List<String> options, String label, bool showSecondary)
		{
			_innerOptions = new BindingList<String>(options);
			_innerOptionsComboBox.DataSource = _innerOptions;

			_innerOptionsLabel.Text = label;

			_innerOptionsLabel.Visible = true;
			_innerOptionsComboBox.Visible = true;

			_secondaryOptionComboBox.Visible = showSecondary;
			_secondaryOptionLabel.Visible = showSecondary;
		}

		private void RemoveDuplicates(DataTable table)
		{
			for (int i = 0; i < table.Rows.Count; i++)
			{
				for (int j = i + 1; j < table.Rows.Count; j++)
				{
					DataRow one = table.Rows[i];
					DataRow two = table.Rows[j];
					if (DataRowEqual(one, two))
					{
						table.Rows[j].Delete();
						table.AcceptChanges();
					}
				}
			}
		}

		private bool DataRowEqual(DataRow one, DataRow two)
		{
			if (one.ItemArray.Length != two.ItemArray.Length)
				return false;

			for (int i = 0; i < one.ItemArray.Length; i++)
			{
				if (!one[i].Equals(two[i]))
					return false;
			}

			return true;
		}

		private List<String> GetDepartmentNames()
		{
			List<String> names = new List<String>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(DepartmentNamesCommandString, connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["dept_name"].ToString() + " - " + reader["dept_no"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}

			return names;
		}

		private List<String> GetVendors()
		{
			List<String> names = new List<String>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(VendorNamesCommandString, connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["vendor"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private List<String> GetGroups()
		{
			List<String> names = new List<String>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(GroupNamesCommandString, connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["PGCode"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private List<String> GetSections()
		{
			List<String> names = new List<string>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand comamnd = new SqlCommand(SectionNamesCommandString, connection))
					{
						using (SqlDataReader reader = comamnd.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["section_name"].ToString().Trim() + " - " + reader["section"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private List<String> GetRehangs()
		{
			List<String> names = new List<string>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(RehangNamesCommandString, connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["Rehang"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private List<String> GetAisles()
		{
			List<String> names = new List<string>();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(AislesCommandString, connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["LocAisle"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private List<String> GetBlockNumbers(String aisle)
		{
			List<String> names = new List<string>();
			names.Add("All");
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(GetBlockNumbersCommandString(aisle), connection))
					{
						using (SqlDataReader reader = command.ExecuteReader())
						{
							while (reader.Read())
								names.Add(reader["LocBlock"].ToString());
						}
					}
					connection.Close();
				}
			}
			catch
			{
				throw;
			}
			return names;
		}

		private void modifiedDateSearch()
		{
			if (_btnModifiedDate.Checked)
			{
				_dateTimePicker.Enabled = true;
				_dateTimePicker2.Enabled = true;

				String commandString = "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
					"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq FROM " +
					"POSplus_TagLoc_Products " + GetPrintTagFlagString(true) + ") prods INNER JOIN " +
					"(SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString + ") AND " +
					"Modified BETWEEN '" + _dateTimePicker.Value.ToString("yyyy-MM-dd") + "' AND '" + (_dateTimePicker2.Value + new TimeSpan(1,0,0,0)).ToString("yyyy-MM-dd") + "') batches " +
					"ON prods.Upc = batches.Upc ORDER BY prods.Upc";

				DataTable newTop = GetDataFromCommandString(commandString);

				_topView.Focus();
				ClearDataTable(_top);
				_top = newTop;
				BindDataSource(_topView, _top);
			}
		}

		private DataTable GetDataFromCommandString(String commandString)
		{
			DataTable result = new DataTable();
			try
			{
				using (SqlConnection connection = new SqlConnection(_instanceRef.ConnectionString))
				{
					connection.Open();
					using (SqlCommand command = new SqlCommand(commandString, connection))
					{
						using (SqlDataAdapter adapter = new SqlDataAdapter(command))
						{
							adapter.Fill(result);
						}
					}
					connection.Close();
				}
			}
			catch
			{
				//throw;
			}
			return result;
		}

		protected String GetItemsFromDepartmentCommandString(String departmentName)
		{
			String ptf = GetPrintTagFlagString(false);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq "
				+ "FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq "
				+ "FROM POSplus_TagLoc_Products WHERE Department = " + departmentName + ptf
				+ ") prods INNER JOIN (SELECT upc FROM " + _table + " WHERE BatchNo IN (" 
				+ BatchNoString + ")) batches ON prods.Upc = batches.Upc";
		}

		protected String GetItemsFromVendorCommandString(String vendor)
		{
			String ptf = GetPrintTagFlagString(false);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products WHERE Vendor = " + vendor + ptf +
				") prods INNER JOIN (SELECT Upc FROM " + _table + " WHERE BatchNo IN (" +
				BatchNoString + ")) batches ON prods.Upc = batches.Upc";
		}

		protected String GetItemsFromGroupCommandString(String group)
		{
			String ptf = GetPrintTagFlagString(true);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT upc FROM ProductGroupDetail WHERE PGCode = '" + group + "') groups " + 
				"INNER JOIN (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products " + ptf + ") prods ON groups.Upc = prods.Upc INNER JOIN " +
				"(SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString + 
				")) batches ON groups.Upc = batches.upc";
		}

		protected String GetItemsFromSectionCommandString(String section)
		{
			String ptf = GetPrintTagFlagString(false);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products WHERE Section = " + section + ptf +
				") prods INNER JOIN (SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString +
				")) batches ON prods.Upc = batches.Upc";
		}

		protected String GetItemsFromRehangCommandString(String rehang)
		{
			String ptf = GetPrintTagFlagString(true);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products " + ptf + ") prods INNER JOIN (SELECT Upc FROM " +
				_table + " WHERE Rehang = '" + rehang + "' AND BatchNo IN (" + BatchNoString +
				")) batches ON prods.Upc = batches.Upc";
		}

		protected String GetAllItems()
		{
			String ptf = GetPrintTagFlagString(true);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " + 
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products " + ptf + ") prods INNER JOIN (SELECT Upc FROM " +
				_table + " WHERE BatchNo IN (" + BatchNoString + ")) batches ON prods.Upc = batches.Upc";
		}

		protected String GetItemsFromSubscriptionCommandString(String aisle)
		{
			String ptf = GetPrintTagFlagString(false);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products WHERE LocAisle = " + aisle + ptf + ") prods INNER JOIN " +
				"(SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString + ")) batches ON " + 
				"prods.Upc = batches.Upc";
		}

		protected String GetItemsFromSubscriptionCommandString(String aisle, String block)
		{
			String ptf = GetPrintTagFlagString(false);

			return "SELECT prods.Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM (SELECT Upc, Cert_Code, Description, Size, LocAisle, LocBlock, LocSeq " +
				"FROM POSplus_TagLoc_Products WHERE LocAisle = " + aisle + " AND LocBlock = " + block +
				ptf + ") prods INNER JOIN (SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString +
				")) batches ON prods.Upc = batches.Upc";
		}

		private String GetPrintTagFlagString(bool withWhere)
		{
			String result = "";

			if (_btnY.Checked)
				result = " AND SVTregPrintTagFlag = 'Y' ";
			else if (_btnN.Checked)
				result = " AND SVTregPrintTagFlag = 'N'";

			if (withWhere && result.Length > 0)
				result = " WHERE " + result.Substring(4);

			return result;				
		}

		protected String GetBlockNumbersCommandString(String aisle)
		{
			return "SELECT prods.LocBlock FROM (SELECT LocBlock, Upc FROM POSplus_TagLoc_Products WHERE LocAisle = " + aisle +
				") prods INNER JOIN (SELECT Upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString + ")) batches ON " +
				"prods.Upc = batches.Upc GROUP BY prods.LocBlock ORDER BY prods.LocBlock";
		}

		protected String DepartmentNamesCommandString
		{
			get
			{
				return "SELECT dept_name, dept_no FROM Departments INNER JOIN (SELECT department FROM " + _table + " WHERE BatchNo IN ("
					+ BatchNoString + ")) batches ON Departments.dept_no = batches.department GROUP BY dept_name, dept_no ORDER BY dept_name";
			}
		}

		protected String VendorNamesCommandString
		{
			get
			{
				return "SELECT vendor FROM Products INNER JOIN (SELECT upc FROM " + _table + 
					" WHERE BatchNo IN (" + BatchNoString + ")) batches ON " +
					"Products.Upc = batches.Upc GROUP BY vendor ORDER BY vendor";
			}
		}

		protected String GroupNamesCommandString
		{
			get
			{
				return "SELECT PGCode FROM Products INNER JOIN (SELECT upc FROM " + _table + " WHERE BatchNo IN (" + BatchNoString +
					")) batches ON Products.Upc = batches.Upc INNER JOIN ProductGroupDetail ON batches.Upc = ProductGroupDetail.Upc " +
					"GROUP BY ProductGroupDetail.PGCode ORDER BY ProductGroupDetail.PGCode";
			}
		}

		protected String SectionNamesCommandString
		{
			get
			{
                return "SELECT sections.section, sections.section_name FROM Products INNER JOIN Sections ON Products.Section = Sections.section INNER JOIN " +
                        "(SELECT upc	FROM " + _table + " WHERE BatchNo IN (" + BatchNoString + ")) bats ON Products.Upc = bats.upc GROUP BY sections.section, sections.section_name ORDER BY sections.section_name";
			}
		}

		protected String RehangNamesCommandString
		{
			get
			{
				return "SELECT Rehang FROM " + _table + " WHERE BatchNo IN (" + BatchNoString +
					") GROUP BY Rehang ORDER BY Rehang";
			}
		}

		protected String AislesCommandString
		{
			get
			{
				return "SELECT LocAisle FROM TagSubscription GROUP BY LocAisle ORDER BY LocAisle";
			}
		}

		private void _innerOptionsComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			DataTable newTop = new DataTable();
			String commandString = "";
			if (_btnDepartment.Checked)
			{
				commandString = GetItemsFromDepartmentCommandString(_innerOptionsComboBox.Text.Split('-')[1].Trim());
			}
			else if (_btnVendor.Checked)
			{
				commandString = GetItemsFromVendorCommandString(_innerOptionsComboBox.Text);
			}
			else if (_btnGroup.Checked)
			{
				commandString = GetItemsFromGroupCommandString(_innerOptionsComboBox.Text);
			}
			else if (_btnSection.Checked)
			{
				commandString = GetItemsFromSectionCommandString(_innerOptionsComboBox.Text.Split('-')[1].Trim());
			}
			else if (_btnRehang.Checked)
			{
				commandString = GetItemsFromRehangCommandString(_innerOptionsComboBox.Text);
			}
			else if (_btnSubscription.Checked)
			{
				_secondaryOptionLabel.Text = "Block: ";
				_secondaryOptions = new BindingList<String>(GetBlockNumbers(_innerOptionsComboBox.Text));
				_secondaryOptionComboBox.DataSource = _secondaryOptions;

				_secondaryOptionComboBox.Visible = true;
				_secondaryOptionLabel.Visible = true;

				if (_secondaryOptionComboBox.Text == "All")
					commandString = GetItemsFromSubscriptionCommandString(_innerOptionsComboBox.Text);
				else
					commandString = GetItemsFromSubscriptionCommandString(_innerOptionsComboBox.Text, _secondaryOptionComboBox.Text);
			}

			newTop = GetDataFromCommandString(commandString);
			_topView.Focus();
			ClearDataTable(_top);
			_top = newTop;
			BindDataSource(_topView, _top);
		}

		private void _secondaryOptionComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			String commandString = "";
			if (_secondaryOptionComboBox.Text == "All")
				commandString = GetItemsFromSubscriptionCommandString(_innerOptionsComboBox.Text);
			else
				commandString = GetItemsFromSubscriptionCommandString(_innerOptionsComboBox.Text, _secondaryOptionComboBox.Text);

			_topView.Focus();
			ClearDataTable(_top);
			_top = GetDataFromCommandString(commandString);
			BindDataSource(_topView, _top);
		}

        private void AdjustWidthComboBox_DropDown(object sender, EventArgs e)
        {
            ComboBox senderBox = (ComboBox)sender;
            int width = senderBox.DropDownWidth;
            Graphics g = senderBox.CreateGraphics();
            Font font = senderBox.Font;
            int vertScrollBarWidth = (senderBox.Items.Count > senderBox.MaxDropDownItems) ? SystemInformation.VerticalScrollBarWidth : 0;

            int newWidth;
            int maxWidth = 0;
            foreach (String s in ((ComboBox)sender).Items)
            {
                newWidth = (int)g.MeasureString(s, font).Width + vertScrollBarWidth;
                if (maxWidth < newWidth)
                    maxWidth = newWidth;
            }

            senderBox.DropDownWidth = maxWidth;
        }
    }
}
